package Clojure

import (
	. "misc/Clojure/parse"
)

func defineCoreFunctions() {
	MainContext.Define("do", NativeFunction{MyFunction: _do})
	MainContext.Define("def", NativeFunction{MyFunction: _def})
	MainContext.Define("repeat", NativeFunction{MyFunction: _repeat})
	MainContext.Define("vector-s", NativeFunction{MyFunction: _vector_s})
	MainContext.Define("==", NativeFunction{MyFunction: _equal})
}

func EvalArgs(args []Node, context *Context) []Node {
	newargs := make([]Node, len(args))
	for i := 0; i < len(args); i++ {
		newargs[i] = Evaluate(args[i], context)
	}
	return newargs
}

func _equal(args []Node, context *Context) Node {
	retBoolNode := &BoolNode{Val: false}
	args = EvalArgs(args, context)
	switch args[0].(type) {
	case *BoolNode:

		v0 := args[0].(*BoolNode)
		v1 := args[1].(*BoolNode)

		if v0.Val == v1.Val {
			retBoolNode.Val = true
		}
	case *ObjectNode:
		v0 := args[0].(*ObjectNode)
		v1 := args[1].(*ObjectNode)
		if v0.Val == v1.Val {
			retBoolNode.Val = true
		}
	case *NumberNode:
		v0 := args[0].(*NumberNode)
		v1 := args[1].(*NumberNode)
		if v0.Val == v1.Val {
			retBoolNode.Val = true
		}
	}

	return retBoolNode
}

func _do(args []Node, context *Context) Node {
	EvalArgs(args, context)
	return nil
}

func _def(args []Node, context *Context) Node {
	args[1] = Evaluate(args[1], context)
	symNode := args[0].(*SymbolNode)
	context.Define(symNode.Val, args[1])
	return nil
}

func _repeat(args []Node, context *Context) Node {
	args = EvalArgs(args, context)
	repeatNumber := args[0].(*NumberNode).Val.(int)
	retVecNode := &VectorNode{}
	//retVecNode.Nodes
	for i := 0; i < repeatNumber; i++ {
		//TODO
	}
	return retVecNode
}

func _vector_s(args []Node, context *Context) Node {
	args = EvalArgs(args, context)
	retVecNode := VectorNode{}
	sizei := args[0].(*NumberNode).Val.(int)
	retVecNode.Nodes = make([]Node, sizei)
	for i := 0; i < sizei; i++ {
		retVecNode.Nodes[i] = args[1]
	}
	return retVecNode
}
